﻿using System;
using System.Security.Cryptography;
using System.Text;

namespace FileSecurityManager.BizEntities.Extensions
{
    public static class Extensions
    {
        #region class members
        private const string SecurePhrase = "FileSecurityManager";
        #endregion

        #region public methods
        /// <summary>
        /// Encrypts the string.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns>Encrypted message</returns>
        public static string EncryptString(this string message)
        {
            byte[] results;
            UTF8Encoding utf8 = new UTF8Encoding();

            // Step 1. We hash the securePhrase using MD5
            // We use the MD5 hash generator as the result is a 128 bit byte array
            // which is a valid length for the TripleDES encoder we use below
            MD5CryptoServiceProvider hashProvider = new MD5CryptoServiceProvider();
            byte[] tdesKey = hashProvider.ComputeHash(utf8.GetBytes(SecurePhrase));

            // Step 2. Create a new TripleDESCryptoServiceProvider object
            // Step 3. Setup the encoder
            TripleDESCryptoServiceProvider tdesAlgorithm = new TripleDESCryptoServiceProvider
                                                               {
                                                                   Key = tdesKey,
                                                                   Mode = CipherMode.ECB,
                                                                   Padding = PaddingMode.PKCS7
                                                               };

            // Step 4. Convert the input string to a byte[]
            byte[] dataToEncrypt = utf8.GetBytes(message);

            // Step 5. Attempt to encrypt the string
            try
            {
                ICryptoTransform encryptor = tdesAlgorithm.CreateEncryptor();
                results = encryptor.TransformFinalBlock(dataToEncrypt, 0, dataToEncrypt.Length);
            }
            finally
            {
                // Clear the TripleDes and Hashprovider services of any sensitive information
                tdesAlgorithm.Clear();
                hashProvider.Clear();
            }

            // Step 6. Return the encrypted string as a base64 encoded string
            return Convert.ToBase64String(results);
        }

        /// <summary>
        /// Decrypts the string.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <returns>Decrypted message</returns>
        public static string DecryptString(this string message)
        {
            byte[] results;
            UTF8Encoding utf8 = new UTF8Encoding();

            // Step 1. We hash the securePhrase using MD5
            // We use the MD5 hash generator as the result is a 128 bit byte array
            // which is a valid length for the TripleDES encoder we use below

            MD5CryptoServiceProvider hashProvider = new MD5CryptoServiceProvider();
            byte[] tdesKey = hashProvider.ComputeHash(utf8.GetBytes(SecurePhrase));

            // Step 2. Create a new TripleDESCryptoServiceProvider object
            // Step 3. Setup the decoder
            TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider
                                                               {
                                                                   Key = tdesKey,
                                                                   Mode = CipherMode.ECB,
                                                                   Padding = PaddingMode.PKCS7
                                                               };
            message = message.Replace(" ", "+");

            // Step 4. Convert the input string to a byte[]
            byte[] dataToDecrypt = Convert.FromBase64String(message);

            // Step 5. Attempt to decrypt the string
            try
            {
                ICryptoTransform decryptor = TDESAlgorithm.CreateDecryptor();
                results = decryptor.TransformFinalBlock(dataToDecrypt, 0, dataToDecrypt.Length);
            }
            finally
            {
                // Clear the TripleDes and Hashprovider services of any sensitive information
                TDESAlgorithm.Clear();
                hashProvider.Clear();
            }

            // Step 6. Return the decrypted string in UTF8 format
            return utf8.GetString(results);
        }
        #endregion
    }
}
